package sc.math;

/**
 * CardinalCurve is a HermiteCurve whose tangents are defined by the points
 * and a tension parameter. This spline creates a curve from one waypoint to
 * another taking into account the waypoints before and after.
 */
public class CardinalCurve extends HermiteCurve {
	
	// The tension value of the curve
	private double tension;
	
	// A constant that effects tightness of curve (derived from tension)
	private double a;

    /**
     * Interpolates between the start point p2 and end point p3 at interval i.
     * 
     * The tension of the curve is defined by t which is usually in the range
     * [0, 1] but can be anything.
     * 
     * A Catmull-Rom curve is just a cardinal curve with a tension of 0.
     * 
     * @param p1
     * 		Control point that comes before the start point
     * @param p2
     * 		Start point of the curve
     * @param p3
     * 		End point of the curve
     * @param p4
     * 		Control point that comes after the end point
     * @param i
     * 		Interval along curve [0, 1]
     * 
     * @return interval between b and c
     */
    public double interval(double p1, double p2, double p3, double p4, double i) {
    	double t1 = a * (p3 - p1);
    	double t2 = a * (p4 - p2);
    	return super.interval(p2, t1, t2, p3, i);
        
    }
    
    /**
	 * Sets the tension of the curve which is usually in the range [0, 1] but
	 * can be anything.
	 * 
	 * Some special tensions:
	 * - A cardinal curve with tension of 0 is called a Catmull-Rom curve
	 * - A cardinal curve with tension of 1 is a straight line
	 * 
	 * @param tension
	 *            Tension of curve
	 */
	public void setTension(double tension) {
		this.tension = tension;
		a = 0.5f * (1 - tension);
	}
	
	/**
	 * Gets the tension of the curve.
	 * 
     * @return tension of curve
	 */
	public double getTension() {
		return tension;
	}
    
    /**
     * Gets the index of the control point from where the curve starts.
     * 
     * This is a fairly pointless method, only needed to enable a generic
     * Spline2D.
     * 
     * @return index of the control point from where the curve starts
     */
    public int startIndex() {
        return 1;
    }
    
    /**
     * Gets the index of the control point from where the curve ends.
     * 
     * This is a fairly pointless method, only needed to enable a generic
     * Spline2D.
     * 
     * @return index of the control point from where the curve ends
     */
    public int endIndex() {
        return 2;
    }

}
